#include "test_album.h"

/*
 * refer to Effective C++ Item9
 */
#include <stdio.h>

class Transaction {
public:
  Transaction();
  virtual ~Transaction() {
    printf("Transaction dctor\n");
  }

  virtual void logTransaction() const = 0;

  virtual void test() const {
    this->test1();
    this->test2();
    this->test3();
  }

  virtual void test1() const {
    printf("Transaction test1\n");
  }

  void test2() const {
    printf("Transaction test2\n");
    printf("Transaction this:%p\n", this);
  }
private:
  // derived class can redefine this function as public, protected, or private,
  // and still keeps polymorphism
  virtual void test3() const {
    printf("Transaction test3\n");
  }
  void init() {
    logTransaction();
  }
};

Transaction::Transaction() {
  // init();  // this will compile, but lead to runtime error

  // won't compile, because the function is pure virtual in this class
  // and the following call is actually a call the the one in this class
  // logTransaction(); 
  printf("Transaction Ctor\n");
}

class BuyTransaction: public Transaction {
public:
  BuyTransaction() {
    printf("BuyTransaction ctor\n");
  }
  virtual void logTransaction() const {
    printf("buy\n");
  }
  ~BuyTransaction() {
    printf("BuyTransaction dctor\n");
  }
  virtual void test1() const {
    printf("BuyTransaction test1\n");
  }

  void test2() const {
    printf("BuyTransaction test2\n");
    printf("BuyTransaction this:%p\n", this);
  }
  void test() const {
    printf("BuyTransaction test\n");
    Transaction::test();
  }
  void test3() const {
    printf("BuyTransaction test3\n");
  }
};

class SellTransaction: public Transaction {
public:
 virtual void logTransaction() const {
   printf("sell\n");
 }
};

namespace ct {
void VirtualFuncTest::Run(int argc, char *argv[]) {
  BuyTransaction t;
  t.test();
  BuyTransaction *dt = &t;
  Transaction *pt = &t;
  dt->test2();
  pt->test2();
}
} // ct
